#include "FramelessWidget.h"
#include "ui_FramelessWidget.h"
#include <QMouseEvent>

FramelessWidget::FramelessWidget(QWidget *parent)
    : QWidget(parent)
{
    ui = new Ui::FramelessWidget();
    ui->setupUi(this);

    setWindowFlag(Qt::FramelessWindowHint);

    setMouseTracking(this);
}

FramelessWidget::~FramelessWidget()
{
    delete ui;
}

void FramelessWidget::setContent(QWidget *content)
{
    ui->contentLayout->removeWidget(m_contentWidget);
    ui->contentLayout->addWidget(content);
    m_contentWidget = content;
    setMouseTracking(content);
}

void FramelessWidget::setIcon(const QPixmap &icon)
{
    ui->icon->setPixmap(icon);
    ui->icon->setHidden(icon.isNull());
}

void FramelessWidget::setTitle(const QString &title)
{
    ui->title->setText(title);
}

void FramelessWidget::on_btnClose_clicked()
{
    close();
}

void FramelessWidget::on_btnMax_clicked()
{
    if (isMaximized())
    {
        ui->btnMax->setText("1");
        showNormal();
        showNormal();
    }
    else
    {
        ui->btnMax->setText("2");
        showMaximized();
        showMaximized();
    }
}

void FramelessWidget::on_btnMin_clicked()
{
    showMinimized();
}

void FramelessWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
    if (ui->titleFrame->geometry().contains(event->localPos().toPoint()) && event->button() == Qt::LeftButton)
    {
        on_btnMax_clicked();
    }
}

void FramelessWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (!isMaximized())
    {
        edge(event->localPos());
        if (m_edgePressed)
        {
            auto _old = geometry();
            auto _newX = event->globalPos().x();
            auto _newY = event->globalPos().y();
            switch (m_edge)
            {
            case Edge_No:
                break;
            case Edge_Right:
                _old.setRight(_newX);
                break;
            case Edge_BottomRight:
                _old.setBottom(_newY);
                _old.setRight(_newX);
                break;
            case Edge_Bottom:
                _old.setBottom(_newY);
                break;
            case Edge_BottomLeft:
                _old.setBottom(_newY);
                _old.setLeft(_newX);
                if (_old.width() < minimumWidth())
                {
                    _old.setLeft(_newX - minimumWidth() + _old.width());
                }
                break;
            case Edge_Left:
                _old.setLeft(_newX);
                if (_old.width() < minimumWidth())
                {
                    _old.setLeft(_newX - minimumWidth() + _old.width());
                }
                break;
            case Edge_TopLeft:
                _old.setTop(_newY);
                if (_old.height() < minimumHeight())
                {
                    _old.setTop(_newY - minimumHeight() + _old.height());
                }
                _old.setLeft(_newX);
                if (_old.width() < minimumWidth())
                {
                    _old.setLeft(_newX - minimumWidth() + _old.width());
                }
                break;
            case Edge_Top:
                _old.setTop(_newY);
                if (_old.height() < minimumHeight())
                {
                    _old.setTop(_newY - minimumHeight() + _old.height());
                }
                break;
            case Edge_TopRight:
                _old.setTop(_newY);
                if (_old.height() < minimumHeight())
                {
                    _old.setTop(_newY - minimumHeight() + _old.height());
                }
                _old.setRight(_newX);
                break;
            default:
                break;
            }
            setGeometry(_old);
        }
        else if (m_titlePressed)
        {
            auto _newPoint = event->globalPos() - m_pressedPoint.toPoint();
            auto _old = geometry();
            _old.moveTopLeft(_newPoint);
            setGeometry(_old);
        }
    }
}

void FramelessWidget::mousePressEvent(QMouseEvent *event)
{
    m_edge = edge(event->localPos());
    if (m_edge != Edge_No)
    {
        m_edgePressed = true;
        m_pressedPoint = event->globalPos();
    }
    else if (ui->titleFrame->geometry().contains(event->localPos().toPoint()))
    {
        m_titlePressed = true;
        m_pressedPoint = event->localPos();
    }
}

void FramelessWidget::mouseReleaseEvent(QMouseEvent *event)
{
    edge(event->localPos());
    m_titlePressed = false;
    m_edgePressed = false;
}

void FramelessWidget::leaveEvent(QEvent *event)
{
    setCursor(Qt::ArrowCursor);
    m_titlePressed = false;
    //m_edgePressed = false;
}

Edge FramelessWidget::edge(const QPointF &pos)
{
    if (ui->btnClose->geometry().contains(pos.toPoint()) ||
        ui->btnMax->geometry().contains(pos.toPoint()) ||
        ui->btnMin->geometry().contains(pos.toPoint()))
    {
        setCursor(Qt::ArrowCursor);
        return Edge_No;
    }
    bool _top = false;
    bool _left = false;
    bool _bottom = false;
    bool _right = false;
    auto _rect = rect();
    if (qAbs(_rect.left() - pos.x()) < 5)
    {
        _left = true;
    }
    if (qAbs(_rect.right() - pos.x()) < 5)
    {
        _right = true;
    }
    if (qAbs(_rect.bottom() - pos.y()) < 5)
    {
        _bottom = true;
    }
    if (qAbs(_rect.top() - pos.y()) < 5)
    {
        _top = true;
    }
    if (_bottom && _left)
    {
        setCursor(Qt::SizeBDiagCursor);
        return Edge_BottomLeft;
    }
    else if (_bottom && _right)
    {
        setCursor(Qt::SizeFDiagCursor);
        return Edge_BottomRight;
    }
    else if (_bottom)
    {
        setCursor(Qt::SizeVerCursor);
        return Edge_Bottom;
    }
    if (_top && _left)
    {
        setCursor(Qt::SizeFDiagCursor);
        return Edge_TopLeft;
    }
    else if (_top && _right)
    {
        setCursor(Qt::SizeBDiagCursor);
        return Edge_TopRight;
    }
    else if (_top)
    {
        setCursor(Qt::SizeVerCursor);
        return Edge_Top;
    }
    else if (_left)
    {
        setCursor(Qt::SizeHorCursor);
        return Edge_Left;
    }
    else if (_right)
    {
        setCursor(Qt::SizeHorCursor);
        return Edge_Right;
    }
    else
    {
        setCursor(Qt::ArrowCursor);
        return Edge_No;
    }
}

void FramelessWidget::setMouseTracking(QWidget *widget)
{
    widget->setMouseTracking(true);
    for (auto obj : widget->children())
    {
        auto _widget = qobject_cast<QWidget *>(obj);
        if (_widget)
        {
            setMouseTracking(_widget);
        }
    }
}